From e5d704d01ea433278b78d2d22dec4c048b065611 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 9 Feb 2006 00:22:38 +0100 Subject: [PATCH] The NAT checksum fixes in patches/linux-2.6.16-rc2/net-csum.patch do not work when port numbers are modified (bug 447). tcp_manip_pkt()/udp_manip_pkt() modify the protocol checksum to reflect the changes to ip addresses and port numbers. When dev_queue_xmit() finds a message with proto_csum_blank set, it calculates a new tcp/udp checksum that includes both the modified port numbers and the modified protocol checksum field... so the change to the port numbers affects the protocol checksum twice. This patch modifies net-csum.patch to remove the checksum mangling for port numbers in tcp_manip_pkt()/udp_manip_pkt() Signed-off-by: Jim Dykman --- patches/linux-2.6.16-rc2/net-csum.patch | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/patches/linux-2.6.16-rc2/net-csum.patch b/patches/linux-2.6.16-rc2/net-csum.patch index a1b4a24c0c..4d7ede0874 100644 --- a/patches/linux-2.6.16-rc2/net-csum.patch +++ b/patches/linux-2.6.16-rc2/net-csum.patch @@ -1,16 +1,14 @@ diff -pruN ../pristine-linux-2.6.16-rc1-git4/net/ipv4/netfilter/ip_nat_proto_tcp.c ./net/ipv4/netfilter/ip_nat_proto_tcp.c --- ../pristine-linux-2.6.16-rc1-git4/net/ipv4/netfilter/ip_nat_proto_tcp.c 2006-02-02 17:39:51.000000000 +0000 +++ ./net/ipv4/netfilter/ip_nat_proto_tcp.c 2006-02-02 17:44:18.000000000 +0000 -@@ -129,10 +129,16 @@ tcp_manip_pkt(struct sk_buff **pskb, +@@ -129,10 +129,14 @@ tcp_manip_pkt(struct sk_buff **pskb, if (hdrsize < sizeof(*hdr)) return 1; - hdr->check = ip_nat_cheat_check(~oldip, newip, + if ((*pskb)->proto_csum_blank) { -+ hdr->check = ip_nat_cheat_check(oldip, ~newip, -+ ip_nat_cheat_check(oldport ^ 0xFFFF, -+ newport, hdr->check)); -+ } else { ++ hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check); ++ } else { + hdr->check = ip_nat_cheat_check(~oldip, newip, ip_nat_cheat_check(oldport ^ 0xFFFF, newport, @@ -18,22 +16,19 @@ diff -pruN ../pristine-linux-2.6.16-rc1-git4/net/ipv4/netfilter/ip_nat_proto_tcp + } return 1; } - + diff -pruN ../pristine-linux-2.6.16-rc1-git4/net/ipv4/netfilter/ip_nat_proto_udp.c ./net/ipv4/netfilter/ip_nat_proto_udp.c --- ../pristine-linux-2.6.16-rc1-git4/net/ipv4/netfilter/ip_nat_proto_udp.c 2006-02-02 17:39:51.000000000 +0000 +++ ./net/ipv4/netfilter/ip_nat_proto_udp.c 2006-02-02 17:44:18.000000000 +0000 -@@ -113,11 +113,19 @@ udp_manip_pkt(struct sk_buff **pskb, +@@ -113,11 +113,16 @@ udp_manip_pkt(struct sk_buff **pskb, newport = tuple->dst.u.udp.port; portptr = &hdr->dest; } - if (hdr->check) /* 0 is a special case meaning no checksum */ - hdr->check = ip_nat_cheat_check(~oldip, newip, -+ + if (hdr->check) { /* 0 is a special case meaning no checksum */ + if ((*pskb)->proto_csum_blank) { -+ hdr->check = ip_nat_cheat_check(oldip, ~newip, -+ ip_nat_cheat_check(*portptr ^ 0xFFFF, -+ newport, hdr->check)); ++ hdr->check = ip_nat_cheat_check(oldip, ~newip, hdr->check); + } else { + hdr->check = ip_nat_cheat_check(~oldip, newip, ip_nat_cheat_check(*portptr ^ 0xFFFF, -- 2.30.2